package eu.tanov.epf.pv.types.project.ui.pages;

import java.util.HashMap;
import java.util.List;
import java.util.Set;

import org.eclipse.epf.uma.CustomCategory;
import org.eclipse.epf.uma.DescribableElement;
import org.eclipse.epf.uma.Section;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.ColumnViewerToolTipSupport;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.TableColumn;

import eu.tanov.epf.pv.types.project.common.util.ProjectFactorConstants;
import eu.tanov.epf.pv.types.project.ui.ProjectActivator;
import eu.tanov.epf.pv.types.projectiteration.common.util.ProjectIterationHelper;
import eu.tanov.epf.pv.types.projectiteration.ui.pages.ProjectIterationQuestionairePage;
import eu.tanov.epf.pv.types.projectpractice.common.util.ProjectPracticeHelper;
import eu.tanov.epf.pv.types.projectpractice.ui.pages.ProjectPracticeDescriptionPage;

public class FeaturedPracticesFromIterationsPage extends WizardPage {

	private CustomCategory container;

	private static final Image CHECKED = ProjectActivator.imageDescriptorFromPlugin(ProjectActivator.PLUGIN_ID, "icons/checked.gif").createImage();
	private static final Image UNCHECKED = ProjectActivator.imageDescriptorFromPlugin(ProjectActivator.PLUGIN_ID, "icons/unchecked.gif")
			.createImage();
	private TableViewer viewer;
	protected ProjectIterationWizardData data;
	private Set<CustomCategory> practices;

	protected FeaturedPracticesFromIterationsPage(String pageName, ProjectIterationWizardData data, CustomCategory customCategory,
			Set<CustomCategory> practices) {
		super(pageName);
		setTitle(pageName);
		setDescription("Select the project practices from previous iterations");
		this.data = data;
		this.container = customCategory;
		this.practices = practices;
	}

	@Override
	public void createControl(Composite parent) {
		Composite container = new Composite(parent, SWT.NULL);
		GridLayout layout = new GridLayout();
		layout.numColumns = 3;
		container.setLayout(layout);
		setControl(container);

		createPracticesTable(container);
	}

	private void createPracticesTable(Composite container) {
		viewer = new TableViewer(container, SWT.FULL_SELECTION);
		GridData gridData = new GridData();
		gridData.verticalAlignment = GridData.FILL;
		gridData.horizontalSpan = 2;
		gridData.grabExcessHorizontalSpace = true;
		gridData.grabExcessVerticalSpace = true;
		gridData.horizontalAlignment = GridData.FILL;

		viewer.getTable().setLayoutData(gridData);
		viewer.getTable().setHeaderVisible(true);
		TableViewerColumn checkboxColumn = createTableViewer(viewer, "!", 50);
		checkboxColumn.setLabelProvider(new ColumnLabelProvider() {
			@Override
			public String getText(Object element) {
				return null;
			}

			@Override
			public Image getImage(Object element) {
				if (((SelectableProjectPractice) element).isSelected()) {
					return CHECKED;
				} else {
					return UNCHECKED;
				}
			}
		});
		checkboxColumn.setEditingSupport(new ProjectPracticeCheckboxEditingSupport(viewer, practices));
		TableViewerColumn contentColumn = createTableViewer(viewer, "Practice", 200);
		contentColumn.setLabelProvider(new ColumnLabelProvider() {
			@Override
			public String getText(Object element) {
				SelectableProjectPractice practice = (SelectableProjectPractice) element;
				return practice.getName();
			}
		});

		TableViewerColumn projectInfoColumn = createTableViewer(viewer, "Projects Info", 200);
		ColumnViewerToolTipSupport.enableFor(viewer);

		// This will display the first project where this practice is used ;)
		projectInfoColumn.setLabelProvider(new ColumnLabelProvider() {
			@Override
			public String getText(Object element) {
				Set<CustomCategory> projects = ((SelectableProjectPractice) element).getProjects();
				return projects.iterator().next().getName();
			}

			@Override
			public String getToolTipText(Object element) {
				Set<CustomCategory> projects = ((SelectableProjectPractice) element).getProjects();
				return generateFactorInfo(projects.iterator().next());
			}

			private String generateFactorInfo(CustomCategory project) {
				StringBuilder res = new StringBuilder("Project Info : " + project.getName());
				String nl = System.getProperty("line.separator");
				res.append(nl);

				Set<String> props = ProjectFactorConstants.getMap().keySet();
				List<Section> sections = project.getPresentation().getSections();
				for (Section section : sections) {
					if (props.contains(section.getSectionName())) {
						res.append(section.getSectionName());
						res.append(" : ");
						res.append(section.getName());
						res.append(nl);
					}
				}
				return res.toString();
			}
		});

		viewer.setContentProvider(new ArrayContentProvider());
		viewer.setInput(getInput());
	}

	public void updatePage() {
		viewer.setInput(getInput());
		viewer.refresh();
	}
	
	public IWizardPage getNextPage() {
		IWizardPage next = super.getNextPage();

		if (next instanceof FeaturedPracticesFromOtherProjectsPage) {
			((FeaturedPracticesFromOtherProjectsPage) next).updatePage();
		}

		return next;
	}

	private Object getInput() {
		HashMap<CustomCategory, SelectableProjectPractice> practices = new HashMap<CustomCategory, SelectableProjectPractice>();

		for (DescribableElement iteration : container.getCategorizedElements()) {
			if (ProjectIterationHelper.isProjectIteration(iteration)) {
				for (DescribableElement practice : ((CustomCategory) iteration).getCategorizedElements()) {
					if (ProjectPracticeHelper.isProjectPractice(practice)) {
						if (isGoodPractice((CustomCategory) practice, (CustomCategory) iteration)) {
							SelectableProjectPractice selectablePractice = practices.get(practice);
							if (selectablePractice == null) {
								selectablePractice = new SelectableProjectPractice((CustomCategory) practice);
								practices.put((CustomCategory) practice, selectablePractice);
							}
							selectablePractice.getProjects().add(container);
						}
					}
				}
			}
		}

		return practices.values();
	}

	private boolean isGoodPractice(CustomCategory practice, CustomCategory iteration) {
		List<Section> iterationSections = iteration.getPresentation().getSections();
		Section practiceSection = getSection(iterationSections, practice.getName());
		if (practiceSection != null) {
			List<Section> evaluationSubSections = practiceSection.getSubSections();

			Section satisfactionSection = getSection(evaluationSubSections, ProjectIterationQuestionairePage.EVALUATION_SECTION);
			if (satisfactionSection == null || ProjectIterationQuestionairePage.LOW.equals(satisfactionSection.getName())) {
				return false;
			}

			Section usageSection = getSection(evaluationSubSections, ProjectIterationQuestionairePage.USAGE_SECTION);
			if (usageSection == null || ProjectIterationQuestionairePage.LOW.equals(usageSection.getName())) {
				return false;
			}
		}

		List<Section> agilitySections = practice.getPresentation().getSections();
		Section agilityMethodSection = getSection(agilitySections, ProjectPracticeDescriptionPage.METHOD_SECTION);

		List<SelectableMethodPractice> methodPractices = data.getMethodPractices(agilityMethodSection.getName());

		Section agilityPracticeSection = getSection(agilitySections, ProjectPracticeDescriptionPage.PRACTICE_SECTION);

		for (SelectableMethodPractice mp : methodPractices) {
			if (mp.getName().equals(agilityPracticeSection.getName()) && mp.isSelected()) {
				return true;
			}
		}

		return false;
	}

	private Section getSection(List<Section> sections, String sectionName) {
		for (int i = 0; i < sections.size(); ++i) {
			if (sections.get(i).getSectionName().equals(sectionName)) {
				return sections.get(i);
			}
		}
		return null;
	}

	private String getSectionName(List<Section> sections, String sectionName) {
		Section section = getSection(sections, sectionName);
		if (section == null) {
			return "";
		}

		return section.getName();
	}

	protected TableViewerColumn createTableViewer(TableViewer viewer, String text, int width) {
		TableViewerColumn columnViewer = new TableViewerColumn(viewer, SWT.NONE);
		final TableColumn column = columnViewer.getColumn();
		column.setText(text);
		column.setWidth(width);
		column.setResizable(true);
		column.setMoveable(true);
		return columnViewer;
	}

}
